package com.k2data.k2app.controller;

import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.k2data.k2app.constant.Constant;
import com.k2data.k2app.domain.BomDTO;
import com.k2data.k2app.domain.DeviceCond;
import com.k2data.k2app.domain.DevicePointDTO;
import com.k2data.k2app.domain.po.TDevice;
import com.k2data.k2app.domain.po.TMonitorLimitValue;
import com.k2data.k2app.domain.po.TMonitorPoint;
import com.k2data.k2app.domain.po.TMonitorVariable;
import com.k2data.k2app.mapper.TDeviceMapper;
import com.k2data.k2app.response.CommonResultResponse;
import com.k2data.k2app.response.PageInfo;
import com.k2data.k2app.response.ResponseHelper;
import com.k2data.k2app.service.TemplateService;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * @author lidong9144@163.com 17-3-15.
 */
@RestController
@RequestMapping("/templates")
public class TemplateController {

    private final TemplateService templateService;
    private final TDeviceMapper tDeviceMapper;

    @Autowired
    public TemplateController(TemplateService templateService, TDeviceMapper tDeviceMapper) {
        this.templateService = templateService;
        this.tDeviceMapper = tDeviceMapper;
    }

    // device begin
    @ApiOperation(value = "添加设备")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "device", value = "device", required = true, dataType = "TDevice", paramType = "body")
    })
    @PostMapping(value = "/devices", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CommonResultResponse> postDevice(@Valid @RequestBody TDevice device) throws Exception {
        return ResponseHelper.success(templateService.insertDevice(device));
    }

    @ApiOperation(value = "更新设备")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "deviceId", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(name = "device", value = "device", required = true, dataType = "TDevice", paramType = "body")
    })
    @PutMapping(value = "/devices/{id}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CommonResultResponse> putDevice(
            @PathVariable("id") Long id,
            @RequestBody TDevice device
    ) throws Exception {
        device.setId(id);

        return ResponseHelper.success(templateService.updateDevice(device));
    }

    @ApiOperation(value = "删除设备")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "deviceId", required = true, dataType = "Long", paramType = "path")
    })
    @DeleteMapping(value = "/devices/{id}")
    public ResponseEntity<CommonResultResponse> deleteDevice(@PathVariable("id") Long id) throws Exception {
        return ResponseHelper.success(templateService.deleteDevice(id));
    }

    @ApiOperation(value = "添加设备测点")
    @PostMapping(value = "/devices/{id}/points", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "deviceId", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(name = "pointId", value = "pointId", required = true, dataType = "Long", paramType = "query")
    })
    @Deprecated
    public ResponseEntity<CommonResultResponse> postDevicePoint(@PathVariable("id") Long id,
                                                                @RequestParam(value = "pointId") Long pointId) throws Exception {
        return ResponseHelper.success(templateService.insertDevicePoint(id, pointId));
    }

    @ApiOperation(value = "删除设备测点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "deviceId", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(name = "rid", value = "rid", required = true, dataType = "Long", paramType = "path")
    })
    @DeleteMapping(value = "/devices/{id}/points/{rid}")
    @Deprecated
    public ResponseEntity<CommonResultResponse> deleteDevicePoints(@PathVariable("id") Long id,
                                                                   @PathVariable("rid") Long rid) throws Exception {
        return ResponseHelper.success(templateService.deleteDevicePoints(id, rid));
    }

    @ApiOperation(value = "添加设备测点, 如果有id就是更新, 没有id就是添加")
    @PostMapping(value = "/devices/points", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "points", value = "points", required = true, dataType = "DevicePointDTO", paramType = "body")
    })
    public ResponseEntity<CommonResultResponse> postDevicePoints(@RequestBody DevicePointDTO points) throws Exception {
        return ResponseHelper.success(templateService.insertDevicePoints(points));
    }

    @ApiOperation(value = "删除设备测点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "rid", value = "rid", required = true, dataType = "Long", paramType = "path")
    })
    @DeleteMapping(value = "/devices/points/{rid}")
    public ResponseEntity<CommonResultResponse> deleteDevicePoint(@PathVariable("rid") Long rid) throws Exception {
        return ResponseHelper.success(templateService.deleteDevicePoint(rid));
    }

    @ApiOperation(value = "设备")
    @GetMapping(value = "/devices")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "parentId", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "type", value = "type(wide, deep)", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "isComponent", value = "是否为组件(0否1是)", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "int", paramType = "query")
    })
    public ResponseEntity<CommonResultResponse> getDevice(
            @RequestParam(value = "id", required = false) Long id,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "isComponent", required = false) Integer isComponent,
            @RequestParam(value = "pageNum", required = false) Integer pageNum,
            @RequestParam(value = "pageSize", required = false) Integer pageSize
    ) throws Exception {
        TDevice cond = new TDevice();
        Long wideId = 0L;
        if (id != null) {
            Long tmp = Constant.YES.equals(isComponent) ? templateService.selectRootDeviceId(id) : id;
            wideId = tmp;
            cond.setId(tmp);
        } else {
            cond.setIsRoot(Constant.YES);
            cond.setParentId(0L);
        }

        int pageNumReal = pageNum == null ? 1 : pageNum;
        int pageSizeReal = pageSize == null ? Constant.DEFAULT_PAGE_SIZE : pageSize;

        if ("deep".equals(type)) {
            int count = tDeviceMapper.selectCount(cond);

            PageInfo pageInfo = new PageInfo(pageNumReal, pageSizeReal, count);

            int fromIndex = pageSizeReal * (pageNumReal - 1);
            if (fromIndex > count) {
                return ResponseHelper.success(Lists.newArrayList());
            }

            PageHelper.startPage(pageNumReal, pageSizeReal);
            List<BomDTO> list = templateService.selectTDeviceBomDeep(cond);

            return ResponseHelper.success(list, pageInfo);
        }

        List<BomDTO> wideList = templateService.selectTDeviceBomWide(wideId);

        int count = wideList.size();
        PageInfo pageInfo = new PageInfo(pageNumReal, pageSizeReal, count);

        int fromIndex = pageSizeReal * (pageNumReal - 1);
        if (fromIndex > count) {
            return ResponseHelper.success(Lists.newArrayList());
        }

        int toIndex = pageSizeReal * pageNumReal;
        if (toIndex > count) {
            toIndex = count;
        }

        return ResponseHelper.success(wideList.subList(fromIndex, toIndex), pageInfo);
    }

    @ApiOperation(value = "设备")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "deviceId", required = true, dataType = "Long", paramType = "path")
    })
    @GetMapping(value = "/devices/{id}")
    public ResponseEntity<CommonResultResponse> getDevice(@PathVariable("id") Long id) throws Exception {
        TDevice cond = new TDevice();
        cond.setId(id);
        List<BomDTO> list = templateService.selectTDeviceBomDeep(cond);

        if (list.isEmpty()) {
            return ResponseHelper.success(Maps.newHashMap());
        }

        return ResponseHelper.success(list.get(0));
    }

    @ApiOperation(value = "设备测点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deviceId", value = "deviceId", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "root_id", value = "根节点id", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "customerId", value = "客户id", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "nameEn", value = "nameEn", dataType = "String", paramType = "query")
    })
    @GetMapping(value = "/monitors/points")
    public ResponseEntity<CommonResultResponse> getDevicePoints(
            @RequestParam(value = "deviceId", required = false) Long deviceId,
            @RequestParam(value = "root_id", required = false) Long rootId,
            @RequestParam(value = "customerId", required = false) Long customerId,
            @RequestParam(value = "nameEn", required = false) String nameEn
            ) throws Exception {
        DeviceCond cond = new DeviceCond();
        cond.setDeviceId(deviceId);
        cond.setRootId(rootId);
        cond.setNameEn(nameEn);
        cond.setCustomerId(customerId);

        return ResponseHelper.success(templateService.selectTDevicePoints(cond));
    }
    @ApiOperation(value = "设备测点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path")
    })
    @GetMapping(value = "/monitors/points/{id}")
    public ResponseEntity<CommonResultResponse> getDevicePoint(@PathVariable("id") Long id) throws Exception {
        DeviceCond cond = new DeviceCond();
        cond.setId(id);

        return ResponseHelper.success(templateService.selectTDevicePoints(cond));
    }

    @ApiOperation(value = "测点变量")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deviceId", value = "deviceId", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "monitorPointId", value = "monitorPointId", dataType = "Long", paramType = "query")
    })
    @GetMapping(value = "/monitors/variables")
    public ResponseEntity<CommonResultResponse> getDeviceVariables(
            @RequestParam(value = "deviceId", required = false) Long deviceId,
            @RequestParam(value = "monitorPointId", required = false) Long monitorPointId) throws Exception {
        DeviceCond cond = new DeviceCond();
        cond.setDeviceId(deviceId);
        cond.setMonitorPointId(monitorPointId);

        return ResponseHelper.success(templateService.selectTDeviceVariables(cond));
    }

    @ApiOperation(value = "测点变量")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path")
    })
    @GetMapping(value = "/monitors/variables/{id}")
    public ResponseEntity<CommonResultResponse> getDeviceVariable(@PathVariable("id") Long id) throws Exception {
        DeviceCond cond = new DeviceCond();
        cond.setId(id);

        return ResponseHelper.success(templateService.selectTDeviceVariables(cond));
    }

    @ApiOperation(value = "设备测点阈值")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "deviceId", value = "deviceId", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "monitorPointId", value = "monitorPointId", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "variableId", value = "variableId", dataType = "Long", paramType = "query"),
            @ApiImplicitParam(name = "deviceNo", value = "deviceNo", dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "channelId", value = "channelId", dataType = "int", paramType = "query"),
            @ApiImplicitParam(name = "level", value = "level", dataType = "int", paramType = "query")
    })
    @GetMapping(value = "/monitors/limits")
    public ResponseEntity<CommonResultResponse> getDeviceLimitValues(
            @RequestParam(value = "deviceId", required = false) Long deviceId,
            @RequestParam(value = "monitorPointId", required = false) Long monitorPointId,
            @RequestParam(value = "variableId", required = false) Long variableId,
            @RequestParam(value = "deviceNo", required = false) String deviceNo,
            @RequestParam(value = "channelId", required = false) Integer channelId,
            @RequestParam(value = "level", required = false) Integer level
            ) throws Exception {
        DeviceCond cond = new DeviceCond();
        cond.setDeviceId(deviceId);
        cond.setMonitorPointId(monitorPointId);
        cond.setVariableId(variableId);
        cond.setDeviceNo(deviceNo);
        cond.setChannelId(channelId);
        cond.setLevel(level);

        return ResponseHelper.success(templateService.selectTDeviceLimit(cond));
    }
    // device end

    // monitor begin
    @ApiOperation(value = "添加测点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "monitorPoint", value = "monitorPoint", required = true, dataType = "TMonitorPoint", paramType = "body")
    })
    @PostMapping(value = "/monitors/points", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CommonResultResponse> postMonitorPoint(@Valid @RequestBody TMonitorPoint monitorPoint) throws Exception {
        return ResponseHelper.success(templateService.insertMonitorPoint(monitorPoint));
    }

    @ApiOperation(value = "更新测点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(name = "monitorPoint", value = "monitorPoint", required = true, dataType = "TMonitorPoint", paramType = "body")
    })
    @PutMapping(value = "/monitors/points/{id}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CommonResultResponse> putMonitorPoint(@PathVariable("id") Long id, @RequestBody TMonitorPoint monitorPoint) throws Exception {
        monitorPoint.setId(id);

        return ResponseHelper.success(templateService.updateMonitorPoint(monitorPoint));
    }

    @ApiOperation(value = "删除测点")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path")
    })
    @DeleteMapping(value = "/monitors/points/{id}")
    public ResponseEntity<CommonResultResponse> deleteMonitorPoint(@PathVariable("id") Long id) throws Exception {
        TMonitorPoint cond = new TMonitorPoint();
        cond.setId(id);

        return ResponseHelper.success(templateService.deleteMonitorPoint(cond));
    }

    @ApiOperation(value = "添加监控指标")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "monitorValue", value = "monitorValue", required = true, dataType = "TMonitorVariable", paramType = "body")
    })
    @PostMapping(value = "/monitors/variables", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CommonResultResponse> postMonitorValue(@Valid @RequestBody TMonitorVariable monitorValue) throws Exception {
        return ResponseHelper.success(templateService.insertMonitorValue(monitorValue));
    }

    @ApiOperation(value = "更新监控指标")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(name = "monitorValue", value = "monitorValue", required = true, dataType = "TMonitorVariable", paramType = "body")
    })
    @PutMapping(value = "/monitors/variables/{id}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CommonResultResponse> putMonitorValue(@PathVariable("id") Long id, @RequestBody TMonitorVariable monitorValue) throws Exception {
        monitorValue.setId(id);

        return ResponseHelper.success(templateService.updateMonitorValue(monitorValue));
    }

    @ApiOperation(value = "删除监控指标")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path")
    })
    @DeleteMapping(value = "/monitors/variables/{id}")
    public ResponseEntity<CommonResultResponse> deleteMonitorValue(@PathVariable("id") Long id) throws Exception {
        TMonitorVariable cond = new TMonitorVariable();
        cond.setId(id);

        return ResponseHelper.success(templateService.deleteMonitorValue(cond));
    }

    @ApiOperation(value = "添加阀值")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "limitValue", value = "limitValue", required = true, dataType = "TMonitorLimitValue", paramType = "body")
    })
    @PostMapping(value = "/monitors/limits", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CommonResultResponse> postMonitorPoint(@Valid @RequestBody TMonitorLimitValue limitValue) throws Exception {
        return ResponseHelper.success(templateService.insertMonitorLimitValue(limitValue));
    }

    @ApiOperation(value = "更新阀值")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(name = "limitValue", value = "limitValue", required = true, dataType = "TMonitorLimitValue", paramType = "body")
    })
    @PutMapping(value = "/monitors/limits/{id}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CommonResultResponse> putMonitorPoint(@PathVariable("id") Long id, @RequestBody TMonitorLimitValue limitValue) throws Exception {
        limitValue.setId(id);

        return ResponseHelper.success(templateService.updateMonitorLimitValue(limitValue));
    }

    @ApiOperation(value = "删除阀值")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path")
    })
    @DeleteMapping(value = "/monitors/limits/{id}")
    public ResponseEntity<CommonResultResponse> putMonitorPoint(@PathVariable("id") Long id) throws Exception {
        TMonitorLimitValue cond = new TMonitorLimitValue();
        cond.setId(id);

        return ResponseHelper.success(templateService.deleteMonitorLimitValue(cond));
    }
    // monitor end

    @ApiOperation(value = "更新监控指标(关键指标)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path")
    })
    @PutMapping(value = "/monitors/variables/{id}/synAttr", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<CommonResultResponse> synAttr(@PathVariable("id") Long id) throws Exception {
        return ResponseHelper.success(templateService.updateDeviceType(id));
    }

}
